#ifndef __ISA_EXT_H_
#define __ISA_EXT_H_

#include "base/simtypes.h"

enum ISA_EXT {
    ISA_EXT_MINIMUM              = 384, // hex values for comparison with gdb disassembly
    ISA_EXT_PRINT_ARGC           = 384, // 0x180
    ISA_EXT_BARRIER_NOFLUSH      = 385, // 0x181
    ISA_EXT_GOTO_REAL            = 386, // 0x182
    ISA_EXT_COMMIT               = 387, // 0x183
    ISA_EXT_LOOP                 = 388, // 0x184
    ISA_EXT_LOOPLABEL            = 389, // 0x185
    ISA_EXT_ULOOP                = 390, // 0x186
    ISA_EXT_PROFILESNPT          = 391, // 0x187
    ISA_EXT_LOOPEXIT             = 392, // 0x188
    ISA_EXT_SYNCSNPTUNLOCK       = 393, // 0x189
    ISA_EXT_GETMYID              = 394, // 0x18a
    ISA_EXT_GETNUMCPUS           = 395, // 0x18b
    ISA_EXT_SIGEXIT              = 396, // 0x18c
    ISA_EXT_PRINT_FMT            = 397, // 0x18d
    ISA_EXT_PRINT_ARGV           = 398, // 0x18e
    ISA_EXT_RF_INSERT            = 399, // 0x18f
    ISA_EXT_RF_CLEAR             = 400, // 0x190
    ISA_EXT_WF_INSERT            = 401, // 0x191
    ISA_EXT_WF_CONTAINS          = 402, // 0x192
    ISA_EXT_WF_CLEAR             = 403, // 0x193
    ISA_EXT_WF_PRELOCK           = 404, // 0x194
    ISA_EXT_WF_LOCK              = 405, // 0x195
    ISA_EXT_WF_UNLOCK            = 406, // 0x196
    ISA_EXT_THEXIT               = 407, // 0x197
    ISA_EXT_FORK                 = 408, // 0x198
    ISA_EXT_CPUHALT              = 409, // 0x199
    ISA_EXT_NUMTHREAD            = 410, // 0x19a
    ISA_EXT_STAT_LOCK            = 411, // 0x19b
    ISA_EXT_STAT_UNLOCK          = 412, // 0x19c
    ISA_EXT_STAT_BAR             = 413, // 0x19d
    ISA_EXT_STAT_BAREND          = 414, // 0x19e
    ISA_EXT_SETPRINT             = 415, // 0x19f
    ISA_EXT_MODE                 = 416, // 0x1a0
    ISA_EXT_THEND                = 417, // 0x1a1
    ISA_EXT_THREADID             = 418, // 0x1a2
    ISA_EXT_SETFORKADDR          = 419, // 0x1a3
    ISA_EXT_SETFORKPHASE         = 420, // 0x1a4
    ISA_EXT_STATS_ENABLE         = 421, // 0x1a5
    ISA_EXT_STATS_DISABLE        = 422, // 0x1a6
    ISA_EXT_BEGINCLOSED          = 423, // 0x1a7
    ISA_EXT_ENDCLOSED            = 424, // 0x1a8
    ISA_EXT_NONT_ENABLE          = 425, // 0x1a9
    ISA_EXT_NONT_DISABLE         = 426, // 0x1aa
    ISA_EXT_RELEASE              = 427, // 0x1ab
    ISA_EXT_PRINT_WARNING        = 428, // 0x1ac
    ISA_EXT_PRINT_BUFFER         = 429, // 0x1ad
    ISA_EXT_SET_IGNORE_PROGRESS  = 430, // 0x1ae
    ISA_EXT_TAKESOWOV            = 431, // 0x1af
    ISA_EXT_UNUSED_432           = 432, // 0x1b0
    ISA_EXT_UNUSED_433           = 433, // 0x1b1
    ISA_EXT_DISCARD_STATE        = 434, // 0x1b2
    ISA_EXT_TAKECHKPT            = 435, // 0x1b3
    ISA_EXT_RSTRCHKPT            = 436, // 0x1b4
    ISA_EXT_VIOS_ENABLE          = 437, // 0x1b5
    ISA_EXT_VIOS_DISABLE         = 438, // 0x1b6
    ISA_EXT_WF_LOCK_EAGER        = 439, // 0x1b7
    ISA_EXT_GETVADDR             = 440, // 0x1b8
    ISA_EXT_BEGINOPEN            = 441, // 0x1b9
    ISA_EXT_ENDOPEN              = 442, // 0x1ba
    ISA_EXT_VALIDATE             = 443, // 0x1bb
    ISA_EXT_OVERHEAD_ENABLE      = 444, // 0x1bc
    ISA_EXT_OVERHEAD_DISABLE     = 445, // 0x1bd
    ISA_EXT_GETDEPTH             = 446, // 0x1be
    ISA_EXT_UNCACHED_SIZE        = 447, // 0x1bf
    ISA_EXT_UNCACHED_SETWORD     = 448, // 0x1c0
    ISA_EXT_UNCACHED_STORE       = 449, // 0x1c1
    ISA_EXT_UNCACHED_LOAD        = 450, // 0x1c2
    ISA_EXT_UNUSED_451           = 451, // 0x1c3
    ISA_EXT_UNUSED_452           = 452, // 0x1c4
    ISA_EXT_GETLOGHEADER         = 453, // 0x1c5
    ISA_EXT_TAKESNAPSHOT         = 454, // 0x1c6
    ISA_EXT_RELEASESNAPSHOT      = 455, // 0x1c7
    ISA_EXT_SETJMP               = 456, // 0x1c8
    ISA_EXT_LONGJMP              = 457, // 0x1c9
    ISA_EXT_VIOS_TYPE            = 458, // 0x1ca
    ISA_EXT_FETCH_EX             = 459, // 0x1cb
    ISA_EXT_PROF_STM_aABORT      = 460, // 0x1cc
    ISA_EXT_PROF_STM_zABORT      = 461, // 0x1cd
    ISA_EXT_PROF_STM_aCOMMIT     = 462, // 0x1ce
    ISA_EXT_PROF_STM_zCOMMIT     = 463, // 0x1cf
    ISA_EXT_PROF_STM_aNEWTHREAD  = 464, // 0x1d0
    ISA_EXT_PROF_STM_zNEWTHREAD  = 465, // 0x1d1
    ISA_EXT_PROF_STM_aREAD       = 466, // 0x1d2
    ISA_EXT_PROF_STM_zREAD       = 467, // 0x1d3
    ISA_EXT_PROF_STM_aSTART      = 468, // 0x1d4
    ISA_EXT_PROF_STM_zSTART      = 469, // 0x1d5
    ISA_EXT_PROF_STM_aSTERILIZE  = 470, // 0x1d6
    ISA_EXT_PROF_STM_zSTERILIZE  = 471, // 0x1d7
    ISA_EXT_PROF_STM_aWRITE      = 472, // 0x1d8
    ISA_EXT_PROF_STM_zWRITE      = 473, // 0x1d9
    ISA_EXT_PROF_STM_aWRITELOCAL = 474, // 0x1da
    ISA_EXT_PROF_STM_zWRITELOCAL = 475, // 0x1db
    ISA_EXT_PROF_STM_SUCCESS     = 476, // 0x1dc
    ISA_EXT_PROF_SIGTM_aBACKOFF  = 477, // 0x1dd
    ISA_EXT_PROF_SIGTM_zBACKOFF  = 478, // 0x1de
    ISA_EXT_PROF_SIGTM_aHANDLER  = 479, // 0x1df
    ISA_EXT_PROF_SIGTM_zHANDLER  = 480, // 0x1e0
    ISA_EXT_LINE_MOVE            = 481, // 0x1e1
    ISA_EXT_GETRETRIES           = 482, // 0x1e2
    ISA_EXT_SIGTHREAD            = 483, // 0x1e3
    ISA_EXT_UNUSED_484           = 484, // 0x1e4
    ISA_EXT_UNUSED_485           = 485, // 0x1e5
    ISA_EXT_SET_SM               = 486, // 0x1e6
    ISA_EXT_CLEAR_SM             = 487, // 0x1e7
    ISA_EXT_JOINSNAPSHOT         = 488, // 0x1e8
    ISA_EXT_LEAVESNAPSHOT        = 489, // 0x1e9
    ISA_EXT_RESETVIOADDR         = 490, // 0x1ea
    ISA_EXT_ENABLE_WATCH         = 491, // 0x1eb
    ISA_EXT_DISABLE_WATCH        = 492, // 0x1ec
    ISA_EXT_SETSNAPSHOT          = 493, // 0x1ed
    ISA_EXT_STAT_WATCH           = 494, // 0x1ee
    ISA_EXT_STAT_WATCHEND        = 495, // 0x1ef
    ISA_EXT_UNUSED_496           = 496, // 0x1f0
    ISA_EXT_GETREGSNAPSHOT       = 497, // 0x1f1
    ISA_EXT_SETSOW               = 498, // 0x1f2
    ISA_EXT_RESETSOW             = 499, // 0x1f3
    ISA_EXT_MAXIMUM              = 500,
    // do not just add new SPRs without reusing UNUSED ones above
};

const char* isa_ext_name (int isa_ext);

#define DECL_ISA_EXT_0_ARG_RET(Name, SPR, /*Clobber*/...) \
    __INLINE__ int Name () { \
        register int value; \
        ISA_EXT_0_ARG_RET(SPR, value, ## __VA_ARGS__); \
        return value; \
    }

#define DECL_ISA_EXT_1_ARG_RET(Name, SPR, Type1, /*Clobber*/...) \
    __INLINE__ int Name (Type1 arg1) { \
        register int value; \
        ISA_EXT_1_ARG_RET(SPR, value, arg1, ## __VA_ARGS__); \
        return value; \
    }

#define DECL_ISA_EXT_2_ARG_RET(Name, SPR, Type1, Type2, /*Clobber*/...) \
    __INLINE__ int Name (Type1 arg1, Type2 arg2) { \
        register int value; \
        ISA_EXT_2_ARG_RET(SPR, value, arg1, arg2, ## __VA_ARGS__); \
        return value; \
    }

#define DECL_ISA_EXT_0_ARG(Name, SPR, /*Clobber*/...) \
    __INLINE__ void Name () { \
        ISA_EXT_0_ARG(SPR, ## __VA_ARGS__); \
    }

#define DECL_ISA_EXT_1_CONST(Name, SPR, Arg1, /*Clobber*/...) \
    __INLINE__ void Name () { \
        ISA_EXT_1_ARG(SPR, Arg1, ## __VA_ARGS__); \
    }

#define DECL_ISA_EXT_1_ARG(Name, SPR, Type1, /*Clobber*/...) \
    __INLINE__ void Name (Type1 arg1) { \
        ISA_EXT_1_ARG(SPR, arg1, ## __VA_ARGS__); \
    }

#define DECL_ISA_EXT_2_ARG(Name, SPR, Type1, Type2, /*Clobber*/...) \
    __INLINE__ void Name (Type1 arg1, Type2 arg2) { \
        ISA_EXT_2_ARG(SPR, arg1, arg2, ## __VA_ARGS__); \
    }

#endif
